/*!
 * Copyright (c)2008-2009, stauren.net
 * @file select.js
 * @class __.widget.Select
 * @author <a href="mailto:stauren@stauren.net">stauren</a>
 * @revision:
 */

__.set("__.widget");
__.log('Select: Class begin.');
(function() {

var _NAME = '__', _SELF = window[_NAME];
if (!_SELF.isSet(_NAME +'.widget.Select')) {
  _SELF.set(_NAME +'.widget.Select');

  _SELF.widget.Select = (function() {

    var _D = _SELF.Dom, _E = _SELF.Event, _L = _SELF.Lang,
    _log = _SELF.log, _QA = _SELF.widget, _C = _SELF.Cookie,
    _WIN = _SELF.config.win, _DOC = _SELF.config.doc,
    _clsPrefix = 'du-select-',
    _cfg = {
      txt : {
        wrongValue : 'the value to be set is wrong',
        prefix : 'du-select: '
      },
      cls : {
        container : _clsPrefix +'ctn',
        icon : _clsPrefix +'icon',
        value : _clsPrefix +'value',
        list : _clsPrefix +'list',
        item : _clsPrefix +'item',
        active : _clsPrefix +'active',
        input : _clsPrefix +'input'
      },
      status : {
      },
      defInstCfg : {
        width : 45,
        height : 20,
        items : { 1 : 'item 1', 2 : 'item 2' },
        zIndex : 100,
        defaultValue : 1,
        ctnZindex : 1,
        fontsize : 13,
        bgSrc : 'http://double-underscore.googlecode.com/svn/trunk/src/select/select.gif',
        bgNormal : '-15px 0',
        bgActive : '0 0',
        onChange : function(newValue, newText) {
        }
      },
      normalZindex : 0
    },
    _error = function(t) {
      throw new Error(_cfg.txt.prefix + t);
    };

    return __.Class.extend({
      version : 1.0,
      cache : {},

      _initCfg: function(config) {
        config = config || {};

        this._config = _L.clone(_cfg.defInstCfg);

        var cfg = this._config, longest = 0;

        _L.e(config, function(o, i) {
          cfg[i] = o;
        }, true);

        if (!('width' in config)) {
          _L.e(config.items, function(o) {
            o = o + '';
            if (o.length > longest) {
              longest = o.length;
            }
          }, true);
          cfg.width = longest * (cfg.fontsize + 1) + 12;
        }
      },
      _createEls : function() {
        var els, config = this._config, linesCss, diff, aChild, values, ua, w;

        ua = _SELF.config.ua;
        w = config.width;
        linesCss = 'height:1px;font-size:1px;line-height:0;';

        diff = [2];
        if (ua.ie > 6) {
          diff = [3];
        }
        if (ua.webkit) {
          diff = [1];
        }

        aChild = [];
        values = this.values;

        _L.e(config.items, function(o, i) {
          aChild.push({
            css : 'padding:2px 14px 0 3px;width:'+(w-21)+'px;background:#fff;', cls : _cfg.cls.item, child : {
              tag : 'nobr', css:'', text : o
            }
          });
          values[o] = i;
        }, true);

        els = {
          css : 'height:'+ config.height + 'px;width:'+w+'px;cursor:pointer;font-size:'+this._config.fontsize+'px;position:relative;z-index:'+_cfg.normalZindex+';', cls : _cfg.cls.container, child : [{
            css : linesCss +'margin:0 1px;background:#d0cece;width:'+(w-2)+'px;overflow:hidden;float:left;display:inline;'
          }, {
            css : 'background:#fff;border:1px solid #d0cece;border-width:0 1px;float:left;', child : [{
              css : linesCss +'border:1px solid #e3e2e2;border-width:0 1px;border-top-color:#0f0;width:'+(w-4)+'px;float:left;'
            }, {
              css : 'height:16px;float:left;padding-left:1px;width:'+(w-3)+'px;', child : [{
                css : 'padding:'+diff[0]+'px 1px 0 3px;float:left;height:13px;line-height:13px;', cls : _cfg.cls.value, text : this._config.items[this.value]
              }, {
                css : 'width:11px;height:16px;float:right;background:transparent url('+config.bgSrc+') no-repeat '+config.bgNormal+';margin-right:1px;', cls : _cfg.cls.icon
              }, {
                css : 'visibility:hidden;', html : '<input type="hidden" value="'+this._config.defaultValue+ '" name="'+ this._config.name +'" class="'+ _cfg.cls.input +'"/>'
              }]
            }, {
              css : linesCss +'border:1px solid #e3e2e2;border-width:0 1px;width:'+(w-4)+'px;float:left;'
            }]
          }, {
            css : linesCss +'margin:0 1px;background:#d0cece;width:'+(w-2)+'px;float:left;display:inline;overflow:hidden;'
          }, {
            cls : _cfg.cls.list, css : 'float:left;position:absolute;left:0px;top:18px;display:none;width:'+(w)+'px;z-index:'+this._config.zIndex, child : [{
              css : 'border:1px solid #D0CECE;/*border-bottom:0;*/background:#fff;padding:1px;text-align:left;', child : {
                tag : 'ul', css : 'list-style:none;padding:0;margin:0;', child : aChild
              }
            }, {
              //css : linesCss +'margin:0 1px;background:#d0cece;width:43px;float:left;display:inline;overflow:hidden;'
            }]
          }]
        };

        _D.addEl(els, this.id);
      },
      _initEls: function() {
        var ctn = _D.f(this.id);
        this.els = {
          ctn : ctn,//out ctn
          innerCtn : _D.f('.'+ _cfg.cls.container, ctn),
          value : _D.f('.'+ _cfg.cls.value, ctn),
          icon : _D.f('.'+ _cfg.cls.icon, ctn),
          list : _D.f('.'+ _cfg.cls.list, ctn),
          input : _D.f('.'+ _cfg.cls.input, ctn)
        };
      },
      _initEventsMap : function() {
      },
      _addEvents : function() {
        var bind = _E.bind, els = this.els;
        _E.on(els.ctn, 'mouseover', bind(this._hlMouseOver, this));
        _E.on(els.ctn, 'mouseout', bind(this._hlMouseOut, this));
        _E.on(_DOC, 'click', bind(this._hlClick, this));
      },
      _hlMouseOut : function(e) {
        this.els.icon.style.backgroundPosition = this._config.bgNormal;
      },
      _hlMouseOver : function(e) {
        e = e || _WIN.event;
        var tar = e.target || e.srcElement, cls = tar.className, els = this.els;

        if (tar == els.value || tar == els.icon || tar == els.value.parentNode) {
          els.icon.style.backgroundPosition = this._config.bgActive;
        } else {
          while (tar != this.els.ctn) {
            if (_D.hasClass(tar, _cfg.cls.item)) {
              this.setActive(tar);
              break;
            }
            tar = tar.parentNode;
          }
        }
      },
      _hlClick : function(e) {
        e = e || _WIN.event;
        var tar = e.target || e.srcElement, cls = tar.className, els = this.els;

        if (!this.listDisplaying && (tar == els.value || tar == els.icon ||
          tar == els.icon.parentNode)) {
          this.show();
        } else {
          if (_D.contains(tar, els.ctn)) {
            while (tar && tar != this.els.ctn) {
              if (_D.hasClass(tar, _cfg.cls.item)) {
                this.set(_L.stripTags(tar.innerHTML), true);
                break;
              }
              tar = tar.parentNode;
            }
          }
          this.hide();
        }
      },
      setActive : function(li) {
        this.clearActive();
        li.style.background = '#428fdc';
        li.style.color = '#fff';
        this.lastActiveItem = li;
      },
      clearActive : function(li) {
        if (this.lastActiveItem) {
          this.lastActiveItem.style.background = '#fff';
          this.lastActiveItem.style.color = '#000';
          this.lastActiveItem = null;
        }
      },
      toggle : function() {
        this.listDisplaying ? this.hide() : this.show();
      },
      show : function() {
        var e = this.els;
        if (!this.listDisplaying) {
          e.list.style.display = 'block';
          e.value.style.background = '#428fdc';
          e.value.style.color = '#fff';
          e.innerCtn.style.zIndex = this._config.ctnZindex;
          this.listDisplaying = true;
        }
      },
      hide : function() {
        var e = this.els;
        if (this.listDisplaying) {
          e.list.style.display = 'none';
          e.value.style.background = '#fff';
          e.value.style.color = '#000';
          e.innerCtn.style.zIndex = _cfg.normalZindex;
          this.listDisplaying = false;
        }
      },
      set : function(newValue, isText) {
        isText = isText === true ? true : false;//default is true

        var el, newText;

        if (isText && newValue in this.values) {
          newText = newValue;
          newValue = this.values[newValue];
        } else {
          newText = this._config.items[newValue];
        }

        if (newValue in this._config.items) {
          el = this.els.value;
          el.innerHTML = '';
          _D.addText(el, newText);
          this.value = newValue;
          this.els.input.value = newValue;
          if (this._config.onChange) {
            this._config.onChange(newValue, newText);
          }
        } else {
          _error(_cfg.txt.wrongValue);
        }
      },

      init : function(id, config) {

        this._initCfg(config);

        this.id = id;
        this.listDisplaying = false;
        this.values = {};
        this.value = this._config.defaultValue;
        this.lastActiveItem = null;
        if (!('name' in config)) {
          this._config.name = id + '_select';
        }

        this._createEls();
        this._initEls();
        this._initEventsMap();
        this._addEvents();
      }
    });
  }());
}
}());
__.log('Select: Class end.');
